package com.cloudfun.campusshare.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

import java.util.List;

/**
 * Created by Huqin on 2019/12/27
 */
@Slf4j
public class ByteUtil {
    /**
     * bytes 转16进制字符串
     *
     * @param bArray
     * @return
     */
    public static String bytesToHexString(byte[] bArray) {
        StringBuilder stringBuffer = new StringBuilder(bArray.length);
        String sTemp;
        for (byte b : bArray) {
            sTemp = Integer.toHexString(0xFF & b);
            if (sTemp.length() < 2)
                stringBuffer.append(0);
            stringBuffer.append(sTemp.toUpperCase());
        }
        return stringBuffer.toString();
    }

    public static String byteToHexString(byte byt) {
        return bytesToHexString(new byte[]{byt});
    }

    /**
     * 16进制字符串转bytes
     *
     * @param hex
     * @return
     */
    public static byte[] hexStringToByte(String hex) {
        int len = 0;
        int num = 0;
        //判断字符串的长度是否是两位
        if (hex.length() >= 2) {
            //判断字符喜欢是否是偶数
            len = (hex.length() / 2);
            num = (hex.length() % 2);
            if (num == 1) {
                hex = "0" + hex;
                len = len + 1;
            }
        } else {
            hex = "0" + hex;
            len = 1;
        }
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }

    /**
     * 字符转数字
     *
     * @param c
     * @return
     */
    private static int toByte(char c) {
        if (c >= 'a')
            return (c - 'a' + 10) & 0x0f;
        if (c >= 'A')
            return (c - 'A' + 10) & 0x0f;
        return (c - '0') & 0x0f;
    }

    public static byte[] merge(List<byte[]> bytes) {
        byte[] res = new byte[]{};
        for (byte[] aByte : bytes) {
            res = ArrayUtils.addAll(res, aByte);
        }
        return res;
    }

    public static byte checkSum(byte[] data, int startIndexInclusive, int endIndexExclusive) {
        int checkSum = 0;
        for (int i = startIndexInclusive; i < endIndexExclusive; i++) {
            checkSum += data[i];
        }
        byte[] checkSumBytes = int2Bytes(checkSum);
        return checkSumBytes[checkSumBytes.length - 1];
    }

    public static byte[] int2Bytes(int num) {
        byte[] bytes = new byte[4];
        //通过移位运算，截取低8位的方式，将int保存到byte数组
        bytes[0] = (byte) (num >>> 24);
        bytes[1] = (byte) (num >>> 16);
        bytes[2] = (byte) (num >>> 8);
        bytes[3] = (byte) num;
        return bytes;
    }

    public static int byteArrayToInt(byte[] bytes) {
        byte[] data;
        if (bytes.length != 4) {
            data = new byte[4];
            System.arraycopy(bytes, 0, data, 4 - bytes.length, bytes.length);
        } else {
            data = bytes;
        }
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (3 - i) * 8;
            value += (data[i] & 0xFF) << shift;
        }
        return value;
    }

    public static byte calculateSum(byte[] data, int startIndexInclusive, int endIndexExclusive) {
        int checkSum = 0;
        for (int i = startIndexInclusive; i < endIndexExclusive; i++) {
            checkSum ^= data[i];
        }
        byte[] checkSumBytes = int2Bytes(checkSum);
        return checkSumBytes[checkSumBytes.length - 1];
    }

    public static byte[] int2Bytes(int num,int round) {
        byte[] bytes = new byte[round];
        if(round == 1){
            bytes[0] = (byte) num;
        }else if(round == 2){
            bytes[0] = (byte) (num >>> 8);
            bytes[1] = (byte) num;
        }
        return bytes;
    }
}